package zload

import (
	"context"
	"encoding/json"

	"gitee.com/youkelike/ziam/zerrors"
	"gitee.com/youkelike/ziam/zredis"
	"gitee.com/youkelike/zlog"
)

// 用于处理 redis 的消息发布

type NotificationCommand string

const (
	// 订阅频道
	RedisPubSubChannel = "notifications"
	// 传递的消息类型
	NoticePolicyChanged NotificationCommand = "PolicyChanged"
	NoticeSecretChanged NotificationCommand = "SecretChanged"
)

// 消息内容对象
type Notification struct {
	Command NotificationCommand `json:"command"`
	Payload string              `json:"payload"`
	// Signature     string              `json:"signature"`
	// SignatureAlgo crypto.Hash         `json:"algorithm"`
}

// func (n *Notification) Sign() {
// 	n.SignatureAlgo = crypto.SHA256
// 	hash := sha256.Sum256([]byte(string(n.Command) + n.Payload))
// 	n.Signature = hex.EncodeToString(hash[:])
// }

// redis 发送端
type RedisNotifier struct {
	store *zredis.RedisCluster
}

// 在 publish 中间件中用到，可以自动捕捉资源操作 url，执行订阅消息发送
func NewRedisNotifier() *RedisNotifier {
	store := &zredis.RedisCluster{}
	return &RedisNotifier{
		store: store,
	}
}

// 发送端单例
var NotifySingleton = NewRedisNotifier()

// 发送订阅消息，
// 在 publish 中间件中调用
func (r *RedisNotifier) Notify(channel string, notif Notification) bool {
	toSend, err := json.Marshal(notif)
	if err != nil {
		zlog.Errorw("marshal notification failed: %s", err.Error())

		return false
	}

	zlog.Debugw("sending notification: %v", notif)

	if err := r.store.Publish(context.Background(), channel, string(toSend)); err != nil {
		if !zerrors.Is(err, zredis.ErrRedisIsDown) {
			zlog.Errorw("send notification failed: %s", err.Error())
		}
		return false
	}

	return true
}
